/**
 * 
 */
package com.hirstlogics.boxarrow.box;

import java.io.StringWriter;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

import com.hirstlogics.boxarrow.model.HasId;
import com.hirstlogics.boxarrow.model.IdManager;
import com.hirstlogics.boxarrow.xml.Persist;

/**
 * @author steve
 *
 */
public abstract class Box implements HasId,Persist {
	
	static public final int ATOMIC_ID = 0;
	static public final int PREDICATE_ID = 1;
	static public final int CONTAINER_ID = 2;
	static public final int MAP_ID = 3;
	static public final int TABLE_ID = 4;
	static public final int HANDLE_ID = 5;
	
	static public String[] BOX_TYPE_NAMES = {"atomic","predicate", "container", "map", "table", "handle" };
	static public int[] BOX_TYPE_IDS = {ATOMIC_ID, PREDICATE_ID, CONTAINER_ID, MAP_ID, TABLE_ID, HANDLE_ID};
	
	int id=IdManager.NULL_ID;
	BoxHolder parent = null;
	
	public int getId() { return id; }
	public void setId(int id) {
		if (this.id==IdManager.NULL_ID) this.id = id; 
		else { // attempt to change id error
			}
		}
	
	public String getFullyQualifiedName() {
		Box parent = getParent();
		String parentName = "";
		if (parent!=null) parentName = parent.getFullyQualifiedName();
		return parentName+"."+getName();
	}
	
	public Box getParent() {
		// navigate an instance of arrow
		Box parent=null;
		return parent;
	}
	
	public void setParent(BoxHolder parent) {
		if (this.parent==null) this.parent=parent; 
		else { // attempt to re-parent	
			}
		}
	
	public void unsetParentId() {
		this.parent = null;
	}

	public void add(Box box) {
		// only containers support add; this should throw it
	}
	
	public abstract String getName();

	public abstract void readContents(XMLStreamReader read);
	
	String xmlRender() {
		StringWriter result = new StringWriter();
		XMLOutputFactory xmlof = XMLOutputFactory.newInstance();
		try {
			XMLStreamWriter writer = xmlof.createXMLStreamWriter(result);
			render(writer);
		} catch (XMLStreamException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result.toString();
	}

	public abstract void render(XMLStreamWriter writer) throws XMLStreamException;
	
	static int lookUp(String type) {
		int returnCode = -1;
		int idx = -1;
		while (++idx<BOX_TYPE_IDS.length && returnCode==-1)
			if (type.equals(BOX_TYPE_NAMES[idx])) returnCode = BOX_TYPE_IDS[idx];
		return returnCode;

	}
	public static Box createInstance( String type, String arg) {
		Box made=null;
		switch(lookUp(type)){
		case ATOMIC_ID: made = new AtomicBox(arg);
		}
		return made;
	}

}
